/* The ns package provides the net-score.org functionality.  */
package ns

/*These are methods for making adjustments to the datastore.

In general they shouldn't be used for production work.
*/

import (
	"appengine"
	"appengine/datastore"
	"fmt"
	"net/http"
	"strconv"
)

func init() {
	http.HandleFunc("/ns/testRecordIt", testRecordIt)
	//http.HandleFunc("/ns/deleteIt", deleteIt)
}

/*Deletes large amounts of data quickly.

/ns/deleteIt?k=<kind>&l=<limit>&o=<offset>

This is used to remove lots of unused data, and is the equivalent of using a
chainsaw.  It is so dangerous that it is commented out so that it does not get
used accidentally.
*/
/*func deleteIt(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	var err error
	kind := r.FormValue("k")
	qOffset, err := strconv.ParseInt(r.FormValue("o"), 0, 64)
	if err != nil {
		c.Errorf("deleteIt:strconv.ParseInt err = %v", err)
		return
	}
	qLimit, err := strconv.ParseInt(r.FormValue("l"), 0, 64)
	if err != nil {
		c.Errorf("deleteIt:strconv.ParseInt err = %v", err)
		return
	}
	q := datastore.NewQuery(kind).KeysOnly().Limit(int(qLimit)).Offset(int(qOffset))
	var trk []*datastore.Key
	if trk, err = q.GetAll(c, nil); err != nil {
		c.Errorf("deleteIt:q.GetAll err = %v", err)
		return
	}
	c.Warningf("deleteIt: deleting %d items", len(trk))
	err = datastore.DeleteMulti(c, trk)
	if err != nil {
		c.Errorf("deleteIt:datastore.DeleteMulti err = %v", err)
		return
	}
	returnString := fmt.Sprintf("%d\n\n%v", len(trk), trk)
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	fmt.Fprintf(w, "%s", returnString)
}*/

/*Converts RawData structs to TestRecord and TestData structs.

/ns/testRecordIt?l=<limit>&o=<offset>

This might be expensive and may need to be run on a backend.  Alternatively we
could break it up into batches.
*/
func testRecordIt(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	var err error
	qOffset, err := strconv.ParseInt(r.FormValue("o"), 0, 64)
	if err != nil {
		c.Errorf("testRecordIt:strconv.ParseInt err = %v", err)
		return
	}
	qLimit, err := strconv.ParseInt(r.FormValue("l"), 0, 64)
	if err != nil {
		c.Errorf("testRecordIt:strconv.ParseInt err = %v", err)
		return
	}
	q := datastore.NewQuery("RawData").Limit(int(qLimit)).Offset(int(qOffset))
	var rds []RawData
	if _, err = q.GetAll(c, &rds); err != nil {
		c.Errorf("testRecordIt:q.GetAll err = %v", err)
		return
	}
	rawDataCount := len(rds)
	trk := make([]*datastore.Key, rawDataCount, rawDataCount)
	tdk := make([]*datastore.Key, rawDataCount, rawDataCount)
	trs := make([]*TestRecord, rawDataCount, rawDataCount)
	tds := make([]*TestData, rawDataCount, rawDataCount)
	for i := range rds {
		rd := rds[i]
		trk[i] = datastore.NewKey(c, "TestRecord", rd.String(), 0, nil)
		tdk[i] = datastore.NewKey(c, "TestData", rd.String(), 0, nil)
		trs[i] = &TestRecord{
			RemoteAddr:     rd.RemoteAddr,
			GetTime:        rd.Date,
			PostTime:       rd.Date + 30,
			UserID:         rd.UserId,
			GetHeader:      rd.Header,
			PostHeader:     rd.Header,
			DevKey:         rd.DevKey,
			TestForm:       rd.TestForm,
			TestDataKey:    tdk[i],
			AppVersionID:   rd.VersionID,
			IndexVersionID: rd.IndexVersionID,
		}
		tds[i] = &TestData{
			GetTime:        rd.Date,
			RemoteAddr:     rd.RemoteAddr,
			RawData:        rd.Body,
			IndexVersionID: rd.IndexVersionID,
			TestForm:       rd.TestForm,
		}
	}
	_, err = datastore.PutMulti(c, trk, trs)
	if err != nil {
		c.Errorf("testRecordIt:datastore.PutMulti err = %v", err)
		return
	}
	_, err = datastore.PutMulti(c, tdk, tds)
	if err != nil {
		c.Errorf("testRecordIt:datastore.PutMulti err = %v", err)
		return
	}
	returnString := fmt.Sprintf("%d\n\n%v", rawDataCount, trs)
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	fmt.Fprintf(w, "%s", returnString)
}
